home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / sync / syncSleep.c < prev    next >
C/C++ Source or Header  |  1991-03-20  |  6KB  |  252 lines

  1. /* 
  2.  * syncSleep.c --
  3.  *
  4.  *    Interface between the timer module and processes that wish to sleep
  5.  *     for a specified period of time.
  6.  *
  7.  * Copyright (C) 1985 Regents of the University of California
  8.  * All rights reserved.
  9.  */
  10.  
  11. #ifndef lint
  12. static char rcsid[] = "$Header: /sprite/src/kernel/sync/RCS/syncSleep.c,v 9.4 91/03/20 11:31:06 kupfer Exp $ SPRITE (Berkeley)";
  13. #endif /* not lint */
  14.  
  15.  
  16. #include <sprite.h>
  17. #include <sync.h>
  18. #include <syncInt.h>
  19. #include <proc.h>
  20. #include <sched.h>
  21. #include <sig.h>
  22. #include <stdlib.h>
  23. #include <timer.h>
  24.  
  25. static Boolean WaitTimeSubr _ARGS_((Timer_Ticks wakeupTime));
  26.  
  27.  
  28.  
  29. /*
  30.  *----------------------------------------------------------------------
  31.  *
  32.  * Sync_WaitTime --
  33.  *
  34.  *    Sleep for the specified period of time.
  35.  *
  36.  * Results:
  37.  *    TRUE if aborted because of a signal, FALSE otherwise.
  38.  *
  39.  * Side effects:
  40.  *    Process is put to sleep.
  41.  *
  42.  *----------------------------------------------------------------------
  43.  */
  44.  
  45. Boolean
  46. Sync_WaitTime(time)
  47.     Time time;        /* Amount of time the process will sleep */
  48. {
  49.     Timer_Ticks ticks;
  50.     Timer_Ticks wakeupTime;
  51.     Timer_Ticks    currentTime;        
  52.  
  53.     /*
  54.      * Convert the passed-in time to ticks format.
  55.      */
  56.  
  57.     Timer_TimeToTicks(time, &ticks);
  58.     Timer_GetCurrentTicks(¤tTime);
  59.     Timer_AddTicks(currentTime, ticks, &wakeupTime);
  60.  
  61.     return(WaitTimeSubr(wakeupTime));
  62. }
  63.  
  64.  
  65. /*
  66.  *----------------------------------------------------------------------
  67.  *
  68.  * Sync_WaitTimeInTicks --
  69.  *
  70.  *    Sleep for the specified period of time. 
  71.  *
  72.  * Results:
  73.  *    TRUE if aborted because of a signal, FALSE otherwise.
  74.  *
  75.  * Side effects:
  76.  *    Process is put to sleep.
  77.  *
  78.  *----------------------------------------------------------------------
  79.  */
  80.  
  81. Boolean
  82. Sync_WaitTimeInTicks(time)
  83.     Timer_Ticks time;        /* Amount of time the process will sleep */
  84. {
  85.     Timer_Ticks    currentTime;        
  86.     Timer_Ticks wakeupTime;
  87.  
  88.     Timer_GetCurrentTicks(¤tTime);
  89.     Timer_AddTicks(currentTime, time, &wakeupTime);
  90.  
  91.     return(WaitTimeSubr(wakeupTime));
  92. }
  93.  
  94.  
  95. /*
  96.  *----------------------------------------------------------------------
  97.  *
  98.  * Sync_WaitTimeInterval --
  99.  *
  100.  *    Sleep for the specified period of time.
  101.  *
  102.  * Results:
  103.  *    TRUE if aborted because of a signal, FALSE otherwise.
  104.  *
  105.  * Side effects:
  106.  *    Process is put to sleep.
  107.  *
  108.  *----------------------------------------------------------------------
  109.  */
  110.  
  111. Boolean
  112. Sync_WaitTimeInterval(interval)
  113.     unsigned int interval;    /* Amount of time the process will sleep */
  114. {
  115.     Timer_Ticks wakeupTime;
  116.     Timer_Ticks    currentTime;        
  117.  
  118.     /*
  119.      * Convert the passed-in time to ticks format.
  120.      */
  121.  
  122.     Timer_GetCurrentTicks(¤tTime);
  123.     Timer_AddIntervalToTicks(currentTime, interval, &wakeupTime);
  124.  
  125.     return(WaitTimeSubr(wakeupTime));
  126. }
  127.  
  128.  
  129. /*
  130.  *----------------------------------------------------------------------
  131.  *
  132.  * WaitTimeSubr --
  133.  *
  134.  *    Sleep until the specified time.  This is done by
  135.  *    atomically scheduling a call to Sync_WakeupProcess and causing
  136.  *    the current process to wait on an event corresponding to its
  137.  *    process control block pointer.
  138.  *
  139.  * Results:
  140.  *    TRUE if aborted because of a signal, FALSE otherwise.
  141.  *
  142.  * Side effects:
  143.  *    Process is put to sleep.
  144.  *
  145.  *----------------------------------------------------------------------
  146.  */
  147.  
  148. static Boolean
  149. WaitTimeSubr(wakeupTime)
  150.     Timer_Ticks wakeupTime;        /* Time when process will wakeup */
  151. {
  152.     Proc_ControlBlock     *procPtr;    
  153.     Timer_QueueElement     wakeupElement;
  154.     Boolean         wokeUp = FALSE;
  155.     Timer_Ticks        currentTime;        
  156.     Boolean        sigPending;
  157.     int            pnum;
  158.  
  159.     
  160.     procPtr = Proc_GetCurrentProc();
  161.     pnum = Mach_GetProcessorNumber();
  162.     wakeupElement.routine    = Sync_WakeupProcess; 
  163.     wakeupElement.clientData = (ClientData) procPtr;
  164.     wakeupElement.time       = wakeupTime;
  165.  
  166.     /*
  167.      * Get the scheduler master lock here.  This is done to ensure that
  168.      * the wakeup call cannot precede the process's going to sleep.
  169.      * SyncEventWaitInt expects the sched_MutexPtr lock to be held upon entry.
  170.      */
  171.  
  172.     MASTER_LOCK(sched_MutexPtr);
  173.     Timer_ScheduleRoutine(&wakeupElement, FALSE);
  174.  
  175.     /*
  176.      * Sleep until the designated time passes.  This is done in a loop,
  177.      * since a process may be awakened by a spurious broadcast.
  178.      */
  179.  
  180.     do {
  181.     if (wokeUp) {
  182.         sync_Instrument[pnum].numSpuriousWakeups++;
  183. #ifdef DEBUG
  184.         printf("Sync_WaitTime: woke up for wrong reason.\n");
  185. #endif /* DEBUG */
  186.     }
  187.     sigPending = SyncEventWaitInt((unsigned int) procPtr, TRUE);
  188.     wokeUp = TRUE;
  189.     Timer_GetCurrentTicks(¤tTime);
  190.     } while (Timer_TickLT(currentTime, wakeupTime) && !sigPending);
  191.  
  192.     (void) Timer_DescheduleRoutine(&wakeupElement);
  193. #ifdef spur
  194.     Mach_InstCountEnd(1);
  195. #endif
  196.     MASTER_UNLOCK(sched_MutexPtr);
  197.  
  198.     return(sigPending);
  199. }
  200.  
  201.  
  202.  
  203. /* STUB procedure */
  204. ENTRY ReturnStatus
  205. Sync_Sleep(time)
  206.     Time time;                  /* time process will sleep */
  207. {
  208.     Timer_Ticks ticks;
  209.     /*
  210.      * Convert the passed-in time to ticks format.
  211.      */
  212.     Timer_TimeToTicks(time, &ticks);
  213.     if (Sync_WaitTimeInTicks(ticks)) {
  214.     return(GEN_ABORTED_BY_SIGNAL);
  215.     } else {
  216.     return(SUCCESS);
  217.     }
  218. }
  219.  
  220.  
  221.  
  222. /*
  223.  *----------------------------------------------------------------------
  224.  *
  225.  * Sync_WakeupProcess --
  226.  *
  227.  *    Perform a broadcast to wake up a process after a timer event
  228.  *    has gone off.  
  229.  *
  230.  *    This routine is equivalent to Sync_SlowBroadcast without the wait flag
  231.  *    and with interrupts disabled.
  232.  *
  233.  * Results:
  234.  *    None.
  235.  *
  236.  * Side effects:
  237.  *    Make the process that was waiting for the timer event runnable.
  238.  *
  239.  *----------------------------------------------------------------------
  240.  */
  241.  
  242. /* ARGSUSED */
  243. void
  244. Sync_WakeupProcess(time, procAddress)
  245.     Timer_Ticks time;        /* passed by Timer module but ignored */
  246.     ClientData procAddress;    /* address of PCB of process to wake up */
  247. {
  248.     MASTER_LOCK(sched_MutexPtr);
  249.     SyncEventWakeupInt((unsigned int) procAddress);
  250.     MASTER_UNLOCK(sched_MutexPtr);
  251. }
  252.